home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
3_0
/
SPIRO_SO
/
FTRIG.C
< prev
next >
Wrap
Text File
|
1989-06-06
|
3KB
|
87 lines
/* FTRIG.C
** This is a function that can be used to speed up sine/cosine
** calculations. It stores the values for sine from 0 - 90 degrees,
** and lets you get at them by table look up, rather than by infinite
** series floating point operations. (infinite is a relative word,
** of course) First used in a program that simulates spirograph, which
** requires lots of sine/cos calculations. The whole thing was getting
** my little Mac Plus down, so I wrote this.
**
** To use it: The first call should be with the FTRIG_INIT function,
** which actually stores all the sine values. Then you can use FTRIG_SINE
** and FTRIG_COS to get sine and cosine values for angles, measured in
** degrees. When you are done, free up the space used by the sine
** storage with the FTRIG_END function.
** As in
** ftrig(FTRIG_INIT, 0); << the '0' is ignored
** ftrig(FTRIG_SINE, 30);
** . . .
** ftrig(FTRIG_END, 0);
**
** History:
** June 6 89, John Nalezny
** Function born
*/
#include <math.h>
#include <MacTypes.h>
#include "ftrig.h"
double ftrig(function, angle)
int function;
int angle;
{
static Handle sine_cache_handle;
int loop;
int reduced_deg, neg_flag;
double *dptr;
/* the BIG IDEA here is to store all the sine values we will need,
** so that we save an infinite series floating point operation
** for each calculation.
** Who says you need a floating point co-processor?
** Only of real interest to people with Mac Plus or lower. Fast
** machines are fast enough so you don't care.
*/
switch (function)
{
case FTRIG_INIT:
sine_cache_handle = NewHandle( 91L * (long)sizeof(double));
HLock(sine_cache_handle); /* lock it down for the moment */
for (loop = 0; loop <= 90; loop++)
{
dptr = (double *)(*sine_cache_handle + loop * sizeof(double));
*dptr = sin((loop * PI) / 180.0);
}
HUnlock(sine_cache_handle);
break;
case FTRIG_END:
DisposHandle(sine_cache_handle);
break;
case FTRIG_COS:
angle += 90; /* then go onto the sine section */
case FTRIG_SINE:
angle = angle % 360; /* sine is periodic, of course */
if (angle > 180)
neg_flag = TRUE;
else
neg_flag = FALSE;
angle = angle % 180;
if( angle < 90) /* first quad */
reduced_deg = angle;
else
reduced_deg = 180 - angle;
/* now we have a 0 <= reduced_deg <= 90 */
dptr = (double *)(*sine_cache_handle + reduced_deg * sizeof(double));
if (neg_flag)
return( -( *dptr) ); /* well OK, 1 floating pt. operation */
else
return( *dptr);
break; /* end of sine/cosine part */
} /* end of switch */
return(0.0); /* a normal sort of thing to return, I guess */
}